Generic Migrations in Fluent Part 2
When using generic models, we had to add migrations “by hand”, something like this:
Continent<SQLiteDatabase>.defaultDatabase = .sqlite
Country<SQLiteDatabase>.defaultDatabase = .sqlite
migrations.add(migration: ContinentMigration<SQLiteDatabase>.self, database: .sqlite)
migrations.add(migration: CountryMigration<SQLiteDatabase>.self, database: .sqlite)
The above example is for .sqlite
.
If we changed the database, we would have to change the specific
code.
What it we could do it in a pure generic way?
Generic Migration Example
import Foundation
import Fluent
public extension MigrationConfig {
public mutating func addVaporCountries<D>(for database: DatabaseIdentifier<D>) where D: QuerySupporting & SchemaSupporting & IndexSupporting & ReferenceSupporting {
Continent<D>.defaultDatabase = database
self.add(migration: ContinentMigration<D>.self, database: database)
Country<D>.defaultDatabase = database
self.add(migration: CountryMigration<D>.self, database: database)
}
}
I usually put that extension to MigrationConfig
in the main
swift
file, for example for a project named
VaporCountries
, I put it in
VaporCountries.swift
file.
Usage
In your configure.swift
just add this code, with the appropriate database:
import VaporCountries
...
migrations.addVaporCountries(for: .sqlite)
Just for kicks, here’s another example, VaporSpices
(another Vapor 3 package.)
import Foundation
import Fluent
public extension MigrationConfig {
public mutating func addVaporSpices<D>(for database: DatabaseIdentifier<D>) where D: QuerySupporting & SchemaSupporting & IndexSupporting & ReferenceSupporting {
Form<D>.defaultDatabase = database
self.add(migration: FormMigration<D>.self, database: database)
Heat<D>.defaultDatabase = database
self.add(migration: HeatMigration<D>.self, database: database)
Technique<D>.defaultDatabase = database
self.add(migration: TechniqueMigration<D>.self, database: database)
Season<D>.defaultDatabase = database
self.add(migration: SeasonMigration<D>.self, database: database)
Volume<D>.defaultDatabase = database
self.add(migration: VolumeMigration<D>.self, database: database)
Weight<D>.defaultDatabase = database
self.add(migration: WeightMigration<D>.self, database: database)
Type<D>.defaultDatabase = database
self.add(migration: TypeMigration<D>.self, database: database)
Function<D>.defaultDatabase = database
self.add(migration: FunctionMigration<D>.self, database: database)
Heat<D>.defaultDatabase = database
self.add(migration: HeatMigration<D>.self, database: database)
Taste<D>.defaultDatabase = database
self.add(migration: TasteMigration<D>.self, database: database)
}
}
SO with one-liner you can add 10 models to (any) your database
migrations.addVaporSpices(for: .sqlite)
//or
migrations.addVaporSpices(for: .psql)
//or
migrations.addVaporSpices(for: .mysql)
Prev: Generic Pre-populated Models in Fluent
Next: Making a New Vapor Package
#tutorial #fluent #vapor #model #migration #db #generic #swift #pub